/*
 * 程序清单：这是一个串口设备接收不定长数据的示例代码
 * 例程导出了 uart_dma_sample 命令到控制终端
 * 命令调用格式：uart_dma_sample uart2
 * 命令解释：命令第二个参数是要使用的串口设备名称，为空则使用默认的串口设备
 * 程序功能：通过串口 uart2 输出字符串"hello RT-Thread!"，并通过串口 uart2 输入一串字符（不定长），再通过数据解析后，使用控制台显示有效数据。
*/

#include <user_serial.h>

#define DBG_TAG "Serial"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

uint8_t * Serial_Buffer(uint8_t index){
    switch(index){
    case 0: return ARM1_GetBeffer();
    case 1: return ARM2_GetBeffer();
    case 2: return Platform2D_GetBeffer();
    case 3: return LoRa_GetBeffer();
    case 4: return Pi_GetBeffer();
    default: return NULL;
    }
}

void Serial_Transmit(uint8_t index,uint8_t *cmd, uint32_t size){
    switch(index){
    case 0: ARM1_Transmit(cmd,size); break;
    case 1: ARM2_Transmit(cmd,size); break;
    case 2: Platform2D_Transmit(cmd,size); break;
    case 3: LoRa_Transmit(cmd,size); break;
    case 4: Pi_Transmit(cmd,size); break;
    default: break;
    }
}

//Platform2D_START========================================================================

#define Platform2D_DEV_NAME                 "uart4"
#define Platform2D_CMD_END                     0X6B
#define Platform2D_DATA_MAXLEN                  32

static struct rt_semaphore Platform2D_rx_sem;
static rt_device_t Platform2DSerial;
static uint8_t Platform2DBuffer[Platform2D_DATA_MAXLEN] = {0};
static uint32_t Platform2D_index = 0;

uint32_t Platform2D_GetIndex(void){
    return Platform2D_index;
}

uint8_t * Platform2D_GetBeffer(void){
    return Platform2DBuffer;
}

void Platform2D_Transmit(uint8_t *cmd, uint32_t size){
    rt_device_write(Platform2DSerial, 0, cmd, size);
}

/* 接收数据回调函数 */
static rt_err_t Platform2D_rx_ind(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    if (size > 0)
    {
        rt_sem_release(&Platform2D_rx_sem);
    }
    return RT_EOK;
}

static char Platform2D_sample_get_char(void)
{
    char ch;

    while (rt_device_read(Platform2DSerial, 0, &ch, 1) == 0)
    {
        rt_sem_control(&Platform2D_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&Platform2D_rx_sem, RT_WAITING_FOREVER);
    }
    return ch;
}

/* 数据解析线程 */
static void Platform2D_data_parsing(void)
{
    char ch;
    while (1)
    {
        ch = Platform2D_sample_get_char();
        if(ch == Platform2D_CMD_END)
        {
            Platform2DBuffer[Platform2D_index++] = ch;
            Platform2DBuffer[Platform2D_index] = '\0';
            Platform2D_index = 0;
            continue;
        }
        Platform2D_index = (Platform2D_index >= Platform2D_DATA_MAXLEN-1) ? Platform2D_DATA_MAXLEN-1 : Platform2D_index;
        Platform2DBuffer[Platform2D_index++] = ch;
    }
}

void Platform2D_serial_init(void)
{
    char str[] = "Platform2D Serial OK!\r\n";

    /* 查找系统中的串口设备 */
    Platform2DSerial = rt_device_find(Platform2D_DEV_NAME);
    if (!Platform2DSerial)
    {
        LOG_E("find %s failed!\n", Platform2D_DEV_NAME);
    }

    /* 初始化信号量 */
    rt_sem_init(&Platform2D_rx_sem, "Platform2D_rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(Platform2DSerial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(Platform2DSerial, Platform2D_rx_ind);
    /* 发送字符串 */
    rt_device_write(Platform2DSerial, 0, str, (sizeof(str) - 1));

    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("Platform2DSerial", (void (*)(void *parameter))Platform2D_data_parsing, RT_NULL, 1024, 5, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        LOG_E("Platform2D Thread No Start!\r\n");
    }
}

//Platform2D_END========================================================================

//Pi_START========================================================================

#define Pi_DEV_NAME                 "uart6"
#define Pi_CMD_END                     '}'
#define Pi_DATA_MAXLEN                  64

static struct rt_semaphore Pi_rx_sem;
static rt_device_t PiSerial;
static uint8_t PiBuffer[Pi_DATA_MAXLEN] = {0};
static uint32_t Pi_index = 0;

uint32_t Pi_GetIndex(void){
    return Pi_index;
}

uint8_t * Pi_GetBeffer(void){
    return PiBuffer;
}

void Pi_Transmit(uint8_t *cmd, uint32_t size){
    rt_device_write(PiSerial, 0, cmd, size);
}

/* 接收数据回调函数 */
static rt_err_t Pi_rx_ind(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    if (size > 0)
    {
        rt_sem_release(&Pi_rx_sem);
    }
    return RT_EOK;
}

static char Pi_sample_get_char(void)
{
    char ch;

    while (rt_device_read(PiSerial, 0, &ch, 1) == 0)
    {
        rt_sem_control(&Pi_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&Pi_rx_sem, RT_WAITING_FOREVER);
    }
    return ch;
}

/* 数据解析线程 */
static void Pi_data_parsing(void)
{
    extern struct rt_semaphore rt_semaphore_pi;
    char ch;
    while (1)
    {
        ch = Pi_sample_get_char();
        if(ch == Pi_CMD_END)
        {
            PiBuffer[Pi_index++] = ch;
            PiBuffer[Pi_index] = '\0';
            Pi_index = 0;
            rt_sem_release(&rt_semaphore_pi);
            LOG_D("%s",Pi_GetBeffer());
            continue;
        }
        Pi_index = (Pi_index >= Pi_DATA_MAXLEN-1) ? Pi_DATA_MAXLEN-1 : Pi_index;
        PiBuffer[Pi_index++] = ch;
    }
}

void Pi_serial_init(void)
{
    char str[] = "Pi Serial OK!\r\n";

    /* 查找系统中的串口设备 */
    PiSerial = rt_device_find(Pi_DEV_NAME);
    if (!PiSerial)
    {
        LOG_E("find %s failed!\n", Pi_DEV_NAME);
    }

    /* 初始化信号量 */
    rt_sem_init(&Pi_rx_sem, "Pi_rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(PiSerial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(PiSerial, Pi_rx_ind);
    /* 发送字符串 */
    rt_device_write(PiSerial, 0, str, (sizeof(str) - 1));

    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("PiSerial", (void (*)(void *parameter))Pi_data_parsing, RT_NULL, 1024, 5, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        LOG_E("Pi Thread No Start!\r\n");
    }
}

//Pi_END=========================================================================

//LoRa_START========================================================================

#define LoRa_DEV_NAME                 "uart5"
#define LoRa_CMD_END                     '}'
#define LoRa_DATA_MAXLEN                  64

static struct rt_semaphore LoRa_rx_sem;
static rt_device_t LoRaSerial;
static uint8_t LoRaBuffer[LoRa_DATA_MAXLEN] = {0};
static uint32_t LoRa_index = 0;

uint32_t LoRa_GetIndex(void){
    return LoRa_index;
}

uint8_t * LoRa_GetBeffer(void){
    return LoRaBuffer;
}

void LoRa_Transmit(uint8_t *cmd, uint32_t size){
    rt_device_write(LoRaSerial, 0, cmd, size);
}

/* 接收数据回调函数 */
static rt_err_t LoRa_rx_ind(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    if (size > 0)
    {
        rt_sem_release(&LoRa_rx_sem);
    }
    return RT_EOK;
}

static char LoRa_sample_get_char(void)
{
    char ch;

    while (rt_device_read(LoRaSerial, 0, &ch, 1) == 0)
    {
        rt_sem_control(&LoRa_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&LoRa_rx_sem, RT_WAITING_FOREVER);
    }
    return ch;
}
/* 数据解析线程 */
static void LoRa_data_parsing(void)
{
    char ch;
    bool packet_started = false;
    while (1)
    {
        ch = LoRa_sample_get_char();

        if(packet_started == false){
            if(ch == '{' || ch == '['){
                packet_started = true;
                LoRa_index = 0;
                LoRaBuffer[LoRa_index++] = ch;
            }
            continue;
        }

        if (ch == LoRa_CMD_END)
        {
            if (LoRa_index < LoRa_DATA_MAXLEN - 1)
            {
                LoRaBuffer[LoRa_index++] = ch;
                LoRaBuffer[LoRa_index] = '\0';
                LoRa_index = 0;
                LOG_W("%s", LoRaBuffer);
            }
            continue;
        }
        else if (ch == 0X5D)
        {
            LoRaBuffer[LoRa_index++] = ch;
            LoRaBuffer[LoRa_index] = '\0';
            // 确保缓冲区中有足够的数据
            if (LoRa_index >= 15)
            {
                int nums[12] = {0};
                int count = 3;

                // 提取数据到 nums 数组
                for (int i = 0; i < 12; i++)
                {
                    nums[i] = LoRaBuffer[i + 1];
                }

                // 构造新的数据
                if (LoRa_index >= 14) // 确保 LoRaBuffer 中有足够的数据
                {
                    LoRaBuffer[0] = '{';
                    LoRaBuffer[1] = '0' + LoRaBuffer[13];
                    LoRaBuffer[2] = ':';

                    for (int i = 0; i < 12; i++)
                    {
                        for (int j = 0; j < nums[i]; j++)
                        {
                            if (count >= LoRa_DATA_MAXLEN - 1)
                                break; // 防止越界
                            LoRaBuffer[count++] = 'A' + i;
                        }
                    }

                    if (count < LoRa_DATA_MAXLEN - 1)
                    {
                        LoRaBuffer[count++] = '}';
                    }
                    LoRaBuffer[count] = '\0';
                    LOG_W("%s", LoRaBuffer);
                }
            }

            LoRa_index = 0;
            continue;
        }

        // 更新 LoRa_index 并写入数据到缓冲区
        if (LoRa_index < LoRa_DATA_MAXLEN - 1)
        {
            LoRaBuffer[LoRa_index++] = ch;
        }
        else
        {
            // 防止缓冲区溢出
            LoRa_index = 0;
            LoRaBuffer[LoRa_index++] = ch;
        }
    }
}

void LoRa_serial_init(void)
{
    char str[] = "LoRa Serial OK!\r\n";

    /* 查找系统中的串口设备 */
    LoRaSerial = rt_device_find(LoRa_DEV_NAME);
    if (!LoRaSerial)
    {
        LOG_E("find %s failed!\n", LoRa_DEV_NAME);
    }

    /* 初始化信号量 */
    rt_sem_init(&LoRa_rx_sem, "LoRa_rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(LoRaSerial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(LoRaSerial, LoRa_rx_ind);
    /* 发送字符串 */
    rt_device_write(LoRaSerial, 0, str, (sizeof(str) - 1));

    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("LoRaSerial", (void (*)(void *parameter))LoRa_data_parsing, RT_NULL, 1024, 5, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        LOG_E("LoRa Thread No Start!\r\n");
    }
}

//LoRa_END=========================================================================

//ARM2_START========================================================================

#define ARM2_DEV_NAME                 "uart3"
#define ARM2_CMD_END                     0X6B
#define ARM2_DATA_MAXLEN                  32

static struct rt_semaphore ARM2_rx_sem;
static rt_device_t ARM2Serial;
static uint8_t ARM2Buffer[ARM2_DATA_MAXLEN] = {0};
static uint32_t ARM2_index = 0;

uint32_t ARM2_GetIndex(void){
    return ARM2_index;
}

uint8_t * ARM2_GetBeffer(void){
    return ARM2Buffer;
}

void ARM2_Transmit(uint8_t *cmd, uint32_t size){
    rt_device_write(ARM2Serial, 0, cmd, size);
}

/* 接收数据回调函数 */
static rt_err_t ARM2_rx_ind(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    if (size > 0)
    {
        rt_sem_release(&ARM2_rx_sem);
    }
    return RT_EOK;
}

static char ARM2_sample_get_char(void)
{
    char ch;

    while (rt_device_read(ARM2Serial, 0, &ch, 1) == 0)
    {
        rt_sem_control(&ARM2_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&ARM2_rx_sem, RT_WAITING_FOREVER);
    }
    return ch;
}

/* 数据解析线程 */
static void ARM2_data_parsing(void)
{
    char ch;
    while (1)
    {
        ch = ARM2_sample_get_char();
        if(ch == ARM2_CMD_END)
        {
            ARM2Buffer[ARM2_index++] = ch;
            ARM2Buffer[ARM2_index] = '\0';
            ARM2_index = 0;
            continue;
        }
        ARM2_index = (ARM2_index >= ARM2_DATA_MAXLEN-1) ? ARM2_DATA_MAXLEN-1 : ARM2_index;
        ARM2Buffer[ARM2_index++] = ch;
    }
}

void ARM2_serial_init(void)
{
    char str[] = "ARM2 Serial OK!\r\n";

    /* 查找系统中的串口设备 */
    ARM2Serial = rt_device_find(ARM2_DEV_NAME);
    if (!ARM2Serial)
    {
        LOG_E("find %s failed!\n", ARM2_DEV_NAME);
    }

    /* 初始化信号量 */
    rt_sem_init(&ARM2_rx_sem, "ARM2_rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(ARM2Serial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(ARM2Serial, ARM2_rx_ind);
    /* 发送字符串 */
    rt_device_write(ARM2Serial, 0, str, (sizeof(str) - 1));

    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("ARM2Serial", (void (*)(void *parameter))ARM2_data_parsing, RT_NULL, 1024, 5, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        LOG_E("ARM2 Thread No Start!\r\n");
    }
}

//ARM2_END========================================================================

//ARM1_START========================================================================

#define ARM1_DEV_NAME                 "uart2"
#define ARM1_CMD_END                     0X6B
#define ARM1_DATA_MAXLEN                  32

static struct rt_semaphore ARM1_rx_sem;
static rt_device_t ARM1Serial;
static uint8_t ARM1Buffer[ARM1_DATA_MAXLEN] = {0};
static uint32_t ARM1_index = 0;

uint32_t ARM1_GetIndex(void){
    return ARM1_index;
}

uint8_t * ARM1_GetBeffer(void){
    return ARM1Buffer;
}

void ARM1_Transmit(uint8_t *cmd, uint32_t size){
    rt_device_write(ARM1Serial, 0, cmd, size);
}

/* 接收数据回调函数 */
static rt_err_t ARM1_rx_ind(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断，调用此回调函数，然后发送接收信号量 */
    if (size > 0)
    {
        rt_sem_release(&ARM1_rx_sem);
    }
    return RT_EOK;
}

static char ARM1_sample_get_char(void)
{
    char ch;

    while (rt_device_read(ARM1Serial, 0, &ch, 1) == 0)
    {
        rt_sem_control(&ARM1_rx_sem, RT_IPC_CMD_RESET, RT_NULL);
        rt_sem_take(&ARM1_rx_sem, RT_WAITING_FOREVER);
    }
    return ch;
}

/* 数据解析线程 */
static void ARM1_data_parsing(void)
{
    char ch;
    while (1)
    {
        ch = ARM1_sample_get_char();
        if(ch == ARM1_CMD_END)
        {
            ARM1Buffer[ARM1_index++] = ch;
            ARM1Buffer[ARM1_index] = '\0';
            ARM1_index = 0;
            continue;
        }
        ARM1_index = (ARM1_index >= ARM1_DATA_MAXLEN-1) ? ARM1_DATA_MAXLEN-1 : ARM1_index;
        ARM1Buffer[ARM1_index++] = ch;
    }
}

void ARM1_serial_init(void)
{
    char str[] = "ARM1 Serial OK!\r\n";

    /* 查找系统中的串口设备 */
    ARM1Serial = rt_device_find(ARM1_DEV_NAME);
    if (!ARM1Serial)
    {
        LOG_E("find %s failed!\n", ARM1_DEV_NAME);
    }

    /* 初始化信号量 */
    rt_sem_init(&ARM1_rx_sem, "ARM1_rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(ARM1Serial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(ARM1Serial, ARM1_rx_ind);
    /* 发送字符串 */
    rt_device_write(ARM1Serial, 0, str, (sizeof(str) - 1));

    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("ARM1Serial", (void (*)(void *parameter))ARM1_data_parsing, RT_NULL, 1024, 5, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        LOG_E("ARM1 Thread No Start!\r\n");
    }
}

//ARM1_END========================================================================
